package com.ziyun.pop.modules.storeMaterials.service.impl;


import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ziyun.pop.common.e.DeleteEnum;
import com.ziyun.pop.common.e.material.DirectionEnum;
import com.ziyun.pop.common.e.material.StockMaterialIoTypeEnum;
import com.ziyun.pop.common.e.material.StoreMaterialOutInStatusEnum;
import com.ziyun.pop.common.utils.StorematerialinUtils;
import com.ziyun.pop.common.utils.UserUtils;
import com.ziyun.pop.modules.erpStockLog.entity.ErpStockLogEntity;
import com.ziyun.pop.modules.erpStockLog.service.ErpStockLogService;
import com.ziyun.pop.modules.purchase.entity.StorePurchaseApplyDetailEntity;
import com.ziyun.pop.modules.storeMaterials.dao.StorematerialinOutDao;
import com.ziyun.pop.modules.storeMaterials.entity.*;
import com.ziyun.pop.modules.storeMaterials.entity.dto.StorematerialinOutDto;
import com.ziyun.pop.modules.storeMaterials.service.*;
import com.ziyun.pop.modules.supp.entity.SellerInfoEntity;
import io.renren.common.exception.RRException;
import io.renren.common.utils.PageUtils;
import io.renren.common.utils.R;
import io.renren.common.utils.StringUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Date;


/**
 * @Author ZhaoWei
 * @Date 2018/10/09 11:11
 * @Version V1.0
 */

@Service("storeMaterialInOutService")
public class StoreMaterialInOutServiceImpl extends ServiceImpl<StorematerialinOutDao, StorematerialinOutEntity> implements StoreMaterialInOutService {

	@Autowired
	private StorematerialinOutDao storematerialinOutDao;

	@Autowired
	private StoreMaterialOutDetailService storeMaterialOutDetailService;

	@Autowired
	private StoreStockMaterialIoService storeStockMaterialIoService;

	@Autowired
	private StoreStockMaterialService storeStockMaterialService;

	@Autowired
	private ErpStockLogService erpStockLogService;


	@Override
	public PageUtils queryPageList(Map<String, Object> params) {
			int totalCount = this.baseMapper.getqueryCount(params);
			int current = Integer.valueOf((String) params.get("page"));
			int size = Integer.valueOf((String) params.get("limit"));
			params.put("offset", (current - 1) * size);
			params.put("limit", size);
			List<StorematerialinOutEntity> list = storematerialinOutDao.getQueryList(params);
			return new PageUtils(list, totalCount, size, current);
		}
	@Override
	public List<SellerInfoEntity> getSelectList() {
		return storematerialinOutDao.getSelectMDList();
	}

	@Override
	public BigDecimal getPrice(String materialId,Integer stockId) {
		return storematerialinOutDao.getPricecost(materialId,stockId);
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public R insertApply(StorematerialinOutDto storematerialinOutDto) {
		int sellerId = storematerialinOutDto.getSellerId();
		StorematerialinOutEntity storematerialinOutEntity = storematerialinOutDto.getStorePurchaseApplyEntity();


		// 生成调出单据号
		String transferToNo = StorematerialinUtils.produceTransferToNo(sellerId);

		// 判断调出单据号是否重复 out_no
		boolean isRepeat = false;
		do {
			List<StorematerialinOutEntity> storematerialinOutEntityList = baseMapper.selectList(new QueryWrapper<StorematerialinOutEntity>().eq("out_no", transferToNo));
			if (storematerialinOutEntityList != null && storematerialinOutEntityList.size() > 0) {
				isRepeat = true;
				transferToNo = StorematerialinUtils.produceTransferToNo(sellerId);
			} else {
				isRepeat = false;
			}

		} while (isRepeat);

		storematerialinOutEntity.setOutNo(transferToNo);
		if(storematerialinOutEntity.getType() == null){
			return R.error("出库类型不能为空");
		}
		if(storematerialinOutEntity.getType()==6){
			storematerialinOutEntity.setType(StockMaterialIoTypeEnum.PRODUCTION.toInt());
		}else if(storematerialinOutEntity.getType()==8){
			storematerialinOutEntity.setType(StockMaterialIoTypeEnum.ALLOT_OUT.toInt());
		}else if(storematerialinOutEntity.getType()==4){
			storematerialinOutEntity.setType(StockMaterialIoTypeEnum.SALES_OUT.toInt());
		}else if (storematerialinOutEntity.getType()==5){
			storematerialinOutEntity.setType(StockMaterialIoTypeEnum.INVENTORY_LOSSES.toInt());
		}else{
			throw new RRException("出库类型异常");
		}

		// 调出总价
		BigDecimal totalMoney = new BigDecimal(0);

		// 调出库存明细
		List<StoreMaterialOutDetailEntity> detialListSave = new ArrayList<>();
		List<StoreMaterialOutDetailEntity> storeMaterialOutDetailEntityList = storematerialinOutDto.getStorePurchaseApplyDetailEntityList();
		if(storeMaterialOutDetailEntityList.size()==0){
			return R.error("请添加物料");
		}
		for (StoreMaterialOutDetailEntity storeMaterialOutDetailEntity : storeMaterialOutDetailEntityList) {
			int i = storeMaterialOutDetailEntity.getMaterialQuantity().compareTo(BigDecimal.ZERO);
			if(i==-1){
				return R.error("物料不能添加负数");
			}
			if(i==0){
				return R.error("物料不能为0");
			}
			// 出库数量和实际库存数量比较
			BigDecimal quantity = baseMapper.getStoreStockByQuantity(storeMaterialOutDetailEntity.getMaterialId(),storematerialinOutDto.getStockId());
			if(quantity.compareTo(storeMaterialOutDetailEntity.getMaterialQuantity())==-1){
				return R.error(storeMaterialOutDetailEntity.getMaterialName()+ "库房数量小于出库数量,请重新选择数量");
			}

			if (StringUtil.isNotEmpty(storeMaterialOutDetailEntity.getRemark())) {
				storeMaterialOutDetailEntity.setRemark(storeMaterialOutDetailEntity.getRemark().trim());
			}
			totalMoney = totalMoney.add(storeMaterialOutDetailEntity.getTotalMoney());

			// 单价
			BigDecimal unitPrice = storeMaterialOutDetailEntity.getTotalMoney().divide(storeMaterialOutDetailEntity.getMaterialQuantity(), 2, BigDecimal.ROUND_HALF_UP);
			storeMaterialOutDetailEntity.setUnitMoney(unitPrice);

			detialListSave.add(storeMaterialOutDetailEntity);
		}
		storematerialinOutEntity.setTotalMoney(totalMoney.setScale(2, BigDecimal.ROUND_HALF_UP));

		baseMapper.insert(storematerialinOutEntity);
		storeMaterialOutDetailService.saveBatch(detialListSave, storematerialinOutEntity);
		ErpStockLogEntity erpStockLogEntity = new ErpStockLogEntity();
		erpStockLogEntity.setBillNo(storematerialinOutEntity.getOutNo());
		erpStockLogEntity.setCreateName(storematerialinOutEntity.getCreateName());
		if(storematerialinOutEntity.getType()==5){
			erpStockLogEntity.setType(5);
			erpStockLogEntity.setLogText("盘亏申请记录");
		}else{
			erpStockLogEntity.setType(2);
			erpStockLogEntity.setLogText("调拨出库申请");
		}

		erpStockLogService.saveBatch(erpStockLogEntity);
		return R.ok();
	}

	/**
	 * @author Alix_zw
	 * @Description 出库审核
	 * @Return
	 **/

	@Transactional(rollbackFor = Exception.class)
	@Override
	public R audit(Integer outId) {
		// 仓库
		ErpStockEntity erpStockEntity = baseMapper.getStockBySellerId(UserUtils.getCurentUser().getSellerId(), 1);

		// 判断单据状态
		StorematerialinOutEntity storematerialinOutEntity = baseMapper.selectById(outId);
		if (storematerialinOutEntity == null || storematerialinOutEntity.getStatus() != StoreMaterialOutInStatusEnum.WAIT_AUDIT.toInt()) {
			throw new RuntimeException("出库单不是待审核状态,审核失败");
		}

		List<StoreMaterialOutDetailEntity> storeMaterialOutDetailEntityList = storeMaterialOutDetailService.list(
				new QueryWrapper<StoreMaterialOutDetailEntity>().eq("out_id", outId).eq("del", DeleteEnum.NOT_DELETE.toInt())
		);

		for (StoreMaterialOutDetailEntity storeMaterialOutDetailEntity : storeMaterialOutDetailEntityList) {
			//  根据出库单据号 ， 耗材ID ，查询出库耗材
			StoreMaterialOutDetailEntity baseMapperOutMaterialDetail = baseMapper.getOutMaterialDetail(storematerialinOutEntity.getOutNo(), storeMaterialOutDetailEntity.getMaterialId());

			BigDecimal StockQuantity = baseMapper.getStockQuantity(storeMaterialOutDetailEntity.getMaterialId(),erpStockEntity.getStockId());

			if (StockQuantity.compareTo(baseMapperOutMaterialDetail.getMaterialQuantity()) == -1) {

				throw new RuntimeException("耗材ID是 "+storeMaterialOutDetailEntity.getMaterialId() + " 的库存数量小于实际要出库的数量");

			}

			Map<String, Object> updateMap = new HashMap<>();

			updateMap.put("OutWareHouseQuantity", storeMaterialOutDetailEntity.getMaterialQuantity().doubleValue());

			// 出库数量
			BigDecimal num = baseMapperOutMaterialDetail.getMaterialQuantity();

			// 单价

			BigDecimal price = baseMapperOutMaterialDetail.getUnitMoney();

			num.add(storeMaterialOutDetailEntity.getMaterialQuantity());

			// 判断是出库还是入库的标识
			Integer i = DirectionEnum.REDUCE.toInt();
			BigDecimal bi = new BigDecimal(i.toString());
			BigDecimal quantity = storeMaterialOutDetailEntity.getMaterialQuantity().multiply(bi);

			Date date = new Date();
			//总金额
			BigDecimal moneys = quantity.multiply(price);
			int re;
			re = storeStockMaterialService.updateMaterialWarehouse2(
					quantity
					,date
					,moneys
					,storeMaterialOutDetailEntity.getMaterialId()
					,erpStockEntity.getStockId()
					);
			if(re != 1){
					throw new RuntimeException("库存更新失败");
				}
			// 库存交易明细
			StoreStockMaterialIoEntity storeStockMaterialIoEntity = new StoreStockMaterialIoEntity();
			storeStockMaterialIoEntity.setTicketsNo(storeMaterialOutDetailEntity.getOutNo());
			storeStockMaterialIoEntity.setMaterialId(storeMaterialOutDetailEntity.getMaterialId());
			storeStockMaterialIoEntity.setMaterialQuantity(storeMaterialOutDetailEntity.getMaterialQuantity());
			storeStockMaterialIoEntity.setUnit(storeMaterialOutDetailEntity.getUnit());
			storeStockMaterialIoEntity.setStockId(erpStockEntity.getStockId());
			storeStockMaterialIoEntity.setType(storematerialinOutEntity.getType());
			storeStockMaterialIoEntity.setCreateName(UserUtils.getCurentUser().getUsername());
			storeStockMaterialIoEntity.setDirection(DirectionEnum.REDUCE.toInt());
			storeStockMaterialIoService.save(storeStockMaterialIoEntity);

		}

		Map<String, Object> updateStoreMaterialInOutInMap = new HashMap<>();
		updateStoreMaterialInOutInMap.put("checkName", UserUtils.getCurentUser().getUsername());
		updateStoreMaterialInOutInMap.put("checkTime", new Date());
		updateStoreMaterialInOutInMap.put("status", StoreMaterialOutInStatusEnum.OWAREHOUSE.toInt());
		baseMapper.updateByMap(updateStoreMaterialInOutInMap, storematerialinOutEntity.getOutId());
		ErpStockLogEntity erpStockLogEntity = new ErpStockLogEntity();
		if(storematerialinOutEntity.getType() == 5){
			erpStockLogEntity.setLogText("盘亏审核");
			erpStockLogEntity.setType(5);
		}else{
			erpStockLogEntity.setLogText("调拨出库审核");
			erpStockLogEntity.setType(2);
		}
		erpStockLogEntity.setCreateName(UserUtils.getCurentUser().getUsername());
		erpStockLogEntity.setBillNo(storematerialinOutEntity.getOutNo());
		erpStockLogService.saveBatch(erpStockLogEntity);
		return R.ok("操作成功");
	}

	// 出库驳回
	@Override
	public R reject(Integer outId) {
		StorematerialinOutEntity storematerialinOutEntity = baseMapper.selectById(outId);
		if (storematerialinOutEntity == null || storematerialinOutEntity.getStatus() != StoreMaterialOutInStatusEnum.WAIT_AUDIT.toInt()) {
			return R.error("出库单状态非审核状态,驳回失败!");
		}
		Map<String, Object> updateStoreMaterialInOutInMap = new HashMap<>();
		updateStoreMaterialInOutInMap.put("status", StoreMaterialOutInStatusEnum.REFUCE.toInt());
		updateStoreMaterialInOutInMap.put("checkName", UserUtils.getCurentUser().getUsername());
		updateStoreMaterialInOutInMap.put("checkTime", new Date());
		baseMapper.updateByMap(updateStoreMaterialInOutInMap, storematerialinOutEntity.getOutId());
		ErpStockLogEntity erpStockLogEntity = new ErpStockLogEntity();
		if(storematerialinOutEntity.getType() == 5){
			erpStockLogEntity.setLogText("盘亏审核驳回操作");
			erpStockLogEntity.setType(5);
		}else{
			erpStockLogEntity.setLogText("调拨出库驳回操作");
			erpStockLogEntity.setType(2);
		}
		erpStockLogEntity.setCreateName(UserUtils.getCurentUser().getUsername());
		erpStockLogEntity.setBillNo(storematerialinOutEntity.getOutNo());
		erpStockLogService.saveBatch(erpStockLogEntity);
		return R.ok("操作成功");
	}

	@Override
	public Integer getStockIdBySellerId(int SellerId) {
		return storematerialinOutDao.getSelectStockId(SellerId);
	}

	@Override
	public StorematerialinOutEntity getInfoData(Integer outId) {
		return baseMapper.getInfoData(outId);
	}

	@Override
	public Integer getStockByOutId(Integer outId) {
		return baseMapper.getStockByOutId(outId);
	}

	@Override
	public String getOutNoByOutId(Integer outId) {
		return baseMapper.getOutNoByOutId(outId);
	}
}
